using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Pokemon
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public abstract class Unit : DrawableGameComponent
    {
        #region Attribute

        public enum UnitState
        {
            Idle = 0,
            Attack = 1,       
            Hit = 2,
            Dead = 3,
            Stand = 4,
        };

        protected Sprite[] _textures = new Sprite[5];    //     Khoi tao 5 element chua 5 sprite   

        protected Vector2 _size;

        protected Vector2 _position;                                    //        

        protected int _health;                                          //

        protected int _damage;                                          //
                
        protected UnitState _UnitState;                                 //

        protected static int _delay;                                    //Cho biet thoi gian delay

        protected Color _Color = Color.White;

        protected Unit _enemy;

        protected Blank _owner;

        protected int _range;//////////////Thuoc tinh dung de tinh khoang cach co the ra skill cua 1 unit

        protected TimeSpan _TimeSpan;//Thuoc tinh dung de lam giam toc do thay doi khung hinh cua unit

        protected TimeSpan _delayTimeSpan = TimeSpan.FromSeconds(50);//Thuoc tinh dung de tinh toan thoi gian delay sau 1 loat dan

#endregion

        #region Properties

        public Blank Owner
        {
            get { return _owner; }
            set { _owner = value; }
        }

        public Unit Enemy
        {
            get { return _enemy; }
            set { _enemy = value; }
        }

        public Vector2 Position
        {
            get { return _position; }
            set { _position = value; }
        }

        public Vector2 Size
        {
            get { return _size; }
            set { _size = value; }
        }

        public int Damage
        {
            get { return _damage; }
            set { _damage = value; }
        }

        public Color Color
        {
            get { return _Color; }
            set { _Color = value; }
        }

        public Sprite[] Textures
        {
            get { return _textures; }
        }

        #endregion

        /// <summary>
        /// Ham tra ve so thu tu cua trang thai Unit
        /// </summary>
        /// <returns></returns>
        protected int GetUnitStateIndex()
        {
            var index = 0;
            switch (_UnitState)
            {
                case UnitState.Idle:
                    index = 0;
                    break;
                case UnitState.Attack:
                    index = 1;
                    break;
                case UnitState.Hit:
                    index = 2;
                    break;
                case UnitState.Dead:
                    index = 3;
                    break;
                case UnitState.Stand:
                    index = 4;
                    break;
            }
            return index;
        }


        protected Rectangle GetNextRect()
        {
            var index = GetUnitStateIndex();            
            return
                Textures[index].GetNextRect();                
        }

        /// <summary>
        /// New a instance of Unit
        /// </summary>
        /// <param name="game">Current Game</param>
        /// <param name="owner">Indicate Blank that contain unit</param>
        /// <param name="position">Position of unit in the gameScreen</param>
        protected Unit(Game game, Blank owner, Vector2 position)
            : base(game)
        {
            _owner = owner;

            _position = position;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            _UnitState = UnitState.Idle;
            _size = Textures[GetUnitStateIndex()].Size;
            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {          
            _enemy = LaneManager.GetEnemy(this);
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch sp = Game.Services.GetService(typeof (SpriteBatch)) as SpriteBatch;
            SpriteFont sf =
                ((ScreenManager)(Game.Services.GetService(typeof(ScreenManager)))).SpriteFont;
            if (sp != null)
            {
                Point p = GetCenterPoint();
                sp.DrawString(sf, "!", new Vector2(p.X, p.Y), Color.White);
            }
                
        }

        /// <summary>
        /// Tra ve vi tri tuyet doi cua trong tam cua unit
        /// </summary>
        /// <returns></returns>
        public virtual Point GetCenterPoint()
        {            
            var index = GetUnitStateIndex();
            return 
                new Point((int)_position.X + (int)Textures[index].CenterPoint.X, 
                    (int)_position.Y + (int)Textures[index].CenterPoint.Y);
        }

        public virtual void TakeDamage(int damage, Color color)
        {
            _health -= damage;
            _Color = color;
            if (_health <= 0)
            {
                ((GameplayScreen)(_owner.Owner.Owner)).UnitDestroy(this);
            }                
        }

        protected override void Dispose(bool disposing)
        {
            if (_owner != null)
                _owner.Remove(this);
            //UnloadContent();                  
            base.Dispose(disposing);
        }

        public virtual void Shot(Unit target)
        {
            
        }

        protected void InitNewState()
        {
            _size = Textures[GetUnitStateIndex()].Size;
            NormalizePosition();
            Textures[GetUnitStateIndex()].Reset();
        }

        public virtual void NormalizePosition()
        {
            Vector2 blankSize = Owner.Size;
            Position = new Vector2((blankSize.X - Size.X) / 2 + Owner.Position.X, (blankSize.Y - Size.Y) / 2 + Owner.Position.Y);
        }
    }
}
